package com.hyl.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

/**
 * DispatchServlet
 *
 * @author hyl
 * @date 2025-06-16
 */
public class DispatchServlet extends HttpServlet {

    private Map<String,String> mapper = new HashMap<String,String>();

    @Override
    public void init() throws ServletException {
        super.init();
        // 初始化方法=>映射关系
//        mapper.put("/user/login","com.hyl.servlet.impl.UserServlet.login");
//        mapper.put("/user/reg","com.hyl.servlet.impl.UserServlet.reg");
//        mapper.put("/user/list","com.hyl.servlet.impl.UserServlet.list");
//
//        mapper.put("/dept/list","com.hyl.servlet.impl.DeptServlet.list");
//
//        mapper.put("/role/list","com.hyl.servlet.impl.RoleServlet.list");
//        mapper.put("/role/add","com.hyl.servlet.impl.RoleServlet.list");

        //获取web.xml中配置的init-param节点中的初始化参数
        String packageName = this.getInitParameter("packageName"); //com.hyl.servlet.impl
        if (packageName == null) {
            packageName = "com.hyl.servlet.impl";
        }
        // 初始化方法=>映射关系
        ServletMappingManager servletMappingManager = new ServletMappingManager();
        try {
            mapper = servletMappingManager.loadFile(packageName);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }

    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        execute(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doGet(req, resp);
    }

    protected void execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1、获取请求路径=> /user/list,不含请求前缀
        String path = req.getContextPath();
        String uri = req.getRequestURI().substring(path.length());
        //2、根据请求路径，获取对应的方法
        String mapperName = mapper.get(uri); //com.hyl.servlet.impl.UserServlet.login
        if (mapperName != null) {
            int idx = mapperName.lastIndexOf(".");//获取最后一个.的位置
            String mathodName = mapperName.substring(idx+1); //login
            String className = mapperName.substring(0,idx); //com.hyl.servlet.impl.UserServlet

            //3、通过反射机制，调用方法
            try {
                Class<?> clazz = Class.forName(className); //获取类的字节码文件
                Object obj = clazz.newInstance();//实例化对象
                //遍历类中的所有方法
                //判断方法名是否存在
                //存在，遍历方法的参数
                //获取参数类型、参数的名称
                //获取方法==>调用
                //调用前=》参数赋值
                Method method = obj.getClass().getMethod(mathodName,
                        HttpServletRequest.class, HttpServletResponse.class); //获取方法
                if (method != null) {
                    Object ret = method.invoke(obj,req,resp); //调用方法
                    //4、根据返回值，判断是转发还是重定向
                    toView(ret,req,resp);
                }
            } catch (ClassNotFoundException e) {
                throw new RuntimeException(e);
            } catch (InvocationTargetException e) {
                throw new RuntimeException(e);
            } catch (InstantiationException e) {
                throw new RuntimeException(e);
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            } catch (NoSuchMethodException e) {
                throw new RuntimeException(e);
            }
        }
    }

    private void toView(Object viewName,HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
        if(viewName == null){
            return;
        }
        if (viewName instanceof String) {
            String view = (String) viewName;
            if (view.startsWith("redirect:")) { //转发
                String path = request.getContextPath();
                String redirectPath = view.substring("redirect:".length());
                response.sendRedirect(path+redirectPath);
            } else if (view.startsWith("forward:")) { //重定向
                String forwardPath = view.substring("forward:".length());
                response.sendRedirect(forwardPath);
            }
        }else{
            //异步=》ajax
            response.setContentType("application/json;charset=utf-8");
            response.setCharacterEncoding("utf-8");
            PrintWriter out = response.getWriter();
            out.print(viewName); //{"code":200,"msg":"success","data":[]}
            out.flush();
            out.close();
        }
    }



}


